import sqlite3
from typing import Tuple, List, Dict


class node(object):
    def __init__(self, _value: sqlite3.Row) -> None:
        self.value: sqlite3.Row = _value
        self.after: List[int] = []


def build_trees(all_comments: Tuple[sqlite3.Row]) -> Dict[int, node]:
    """ 从all_comments中, 统计各个节点的后继节点

    :param all_comments: 所有评论
    :return: 一个字典; key为commentID, value为对应的node
    """
    notebook: Dict[int, node] = {}
    # 1. 统计所有节点
    for one_comment in all_comments:
        commentID: int = one_comment['numberID']
        notebook[commentID] = node(one_comment)

    # 2. 统计所有节点的父节点
    for one_comment in all_comments:
        commentID: int = one_comment['numberID']
        parentID: int = one_comment['prevCommentID']
        if parentID in notebook:
            notebook[parentID].after.append(commentID)

    return notebook


def DFS_recursive(all_nodes: Dict[int, node], record: List[sqlite3.Row], current: node) -> None:
    """ DFS递归迭代; 遍历结果写入record

    :param current: 遍历起点
    :param record: 写入结果
    :param all_nodes: 全部节点
    """

    record.append(current.value)
    # 递归终点: 没有子节点
    if len(current.after) <= 0:
        return

    for nextNodeID in current.after:
        if nextNodeID in all_nodes:
            nextNode: node = all_nodes[nextNodeID]
            DFS_recursive(all_nodes, record, nextNode)


def DFS_API(all_nodes: Dict[int, node], current: node) -> Tuple[sqlite3.Row]:
    record = []
    DFS_recursive(all_nodes, record, current)
    return tuple(record)


def show_all(all_comments: Tuple[sqlite3.Row]):
    for row in all_comments:
        print(row['numberID'], end=' ')
    print()


def get_parent_comments(all_comments: Tuple[sqlite3.Row], bottomCommentID: int) -> Tuple[sqlite3.Row]:
    """返回bottomCommentID及其所有父评论

    :param all_comments: 可选择的所有评论
    :param bottomCommentID: 评论ID

    :returns: all_comments的子集
    """
    notebook: Dict[int, sqlite3.Row] = {}
    for comment in all_comments:
        tmpID: int = comment['numberID']
        notebook[tmpID] = comment
    result: List[sqlite3.Row] = []
    ID = bottomCommentID
    while ID >= 0 and (ID in notebook):
        current = notebook[ID]
        result.append(current)
        ID = current['prevCommentID']
    return tuple(reversed(result))


def get_subtree_comments(all_comments: Tuple[sqlite3.Row], rootCommentID: int) -> Tuple[sqlite3.Row]:
    all_nodes: Dict[int, node] = build_trees(all_comments)
    if rootCommentID not in all_nodes:
        return tuple()
    return DFS_API(all_nodes, all_nodes[rootCommentID])


if __name__ == '__main__':
    print('good night')
    test = node(1)
    tmp = test
    tmp.value = 114514
    print(tmp.value, test.value)
    notebook = {
        2: 'ajusduf',
        1: 'ahshs',
        5: 'asydufy',
    }
    for key in notebook:
        print(key, notebook[key])

    conn = sqlite3.connect(
        '../instance/database.bin',
        detect_types=sqlite3.PARSE_DECLTYPES
    )
    conn.row_factory = sqlite3.Row

    SQL_code: str = '''
    SELECT COUNT(*) AS total
    FROM comment;
    '''
    total_count: int = conn.execute(SQL_code).fetchone()['total']
    print('数据库 评论总数:', total_count)

    SQL_code = '''
    SELECT *
    FROM comment;
    '''
    all_comments: List[sqlite3.Row] = conn.execute(SQL_code).fetchall()
    print('数据总数', len(all_comments))
    print('---深度优先遍历----')
    result = get_subtree_comments(all_comments, rootCommentID=1)
    show_all(result)
    print('------遍历上级评论------')
    result = get_parent_comments(all_comments, bottomCommentID=11)
    show_all(result)
